home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 21 / Cream of the Crop 21 (Terry Blount) (October 1996).iso / editor / unite16.zip / UNITE.C < prev    next >
C/C++ Source or Header  |  1996-02-27  |  13KB  |  373 lines

  1. /*
  2.             ╔════════════════════════════════════════╗
  3.             ║                UNITE!                  ║
  4.             ║   Copyright (c) 1994-96 L.I.Williams   ║
  5.             ║          All rights reserved           ║
  6.             ║   Issue 1.6             Date: 27Feb96  ║
  7.             ╚════════════════════════════════════════╝
  8. *~
  9. *~    UNITE.C
  10. *~    Join 2 files outputting lines the same and the differences
  11. *~    If you modify/improve this source, I appreciate a note
  12. *~
  13. */
  14. /***********************************************************************
  15. * HISTORY:
  16. * Date      Iss  Who Comment
  17. * 17-JAN-88 1.0  LIW Created
  18. * 24-AUG-89 1.1  LIW ### End difference added
  19. * 13-DEC-93 1.2  LIW Rename to UNITE
  20. * 12-FEB-94 1.3  LIW Remove free message
  21. * 06-OCT-95 1.5  LIW Format for freeware release
  22. * 20-FEB-96 1.6  LIW Add VENDOR.DOC
  23. ***********************************************************************/
  24. /* standard routines */
  25. #include <stdio.h>
  26. #include <ctype.h>
  27. #include <string.h>
  28.  
  29. /* constants */
  30. #define TRUE 1
  31. #define FALSE 0
  32. /* This module declares the global variables: */
  33. char    ext[40];        /* holds a file name extension */
  34. char    *s1,
  35.     *s2;            /* handy pointers */
  36. char
  37.     prog1[100][192],    /* 100 line buffer for 1st file */
  38.     prog2[100][192],    /* 100 line buffer for 2nd file */
  39.     inpnam1[40],        /* 1st file name store */    
  40.     inpnam2[40];        /* 2nd file name store */
  41. int
  42.     debug,            /* TRUE = lots of debug printout */
  43.     i,
  44.     first1,            /* File1:1st line at which a match is found */
  45.     curr1,            /* File1 the current line being matched */
  46.     beyond1,        /* File1 1 beyond the end of the buffer */
  47.     first2,            /* File2:1st line at which a match is found */
  48.     curr2,            /* File2 the current line being matched */
  49.     beyond2,        /* File2 1 beyond the end of the buffer */
  50.     match;            /* no of lines matched at this point */
  51. char    c;
  52. FILE    *inpfil1;        /* 1st file specified */
  53. FILE    *inpfil2;        /* 2nd file specified */
  54.  
  55. /***********************************************************************
  56. * Debug print routines. These routines only print if /d is specified
  57. * e.g. UNITE FRED1 FRED2 /d > FRED.UNI
  58. * Start of code.
  59. ***********************************************************************/
  60. tprintf (args1)
  61. char    *args1;
  62. {
  63. if (debug) 
  64.   printf (args1);
  65. }
  66. tprintf1 (args1,val1)
  67. char    *args1;
  68. int    val1;
  69. {
  70. if (debug) 
  71.   printf (args1,val1);
  72. }
  73. tprintf2 (args1,val1,val2)
  74. char    *args1;
  75. int    val1;
  76. int    val2;
  77. {
  78. if (debug) 
  79.   printf (args1,val1,val2);
  80. }
  81.  
  82. /***********************************************************************
  83. * Explains parameters etc. 
  84. ***********************************************************************/
  85. void explain()
  86. {
  87. printf("\n\
  88.             ╔════════════════════════════════════════╗\n\
  89.             ║                UNITE!                  ║\n\
  90.             ║   Copyright (c) 1994-96 L.I.Williams   ║\n\
  91.             ║          All rights reserved           ║\n\
  92.             ║   Issue 1.6             Date: 20Feb96  ║\n\
  93.             ╚════════════════════════════════════════╝\n\
  94. ");
  95. printf("\n\UNITE joins or merges two somewhat different versions of the same\n");
  96. printf("text file together. It does a file compare in which the lines that\n");
  97. printf("are the same are output, as well as the differences, which are\n");
  98. printf("highlighted with '### <filename>.' \n");
  99. printf("\n");
  100. printf("Example:  UNITE CONFIG.SYS CONFIG.OLD > CONFIG.JOI\n");
  101. printf("\n");
  102. printf("\
  103. will combine together two versions of CONFIG.SYS in the current directory\n\
  104. and output the combination with the differences highlighted to file\n\
  105. CONFIG.JOI. UNITE is freeware. Send problems, comments, suggestions,\n\
  106. appreciative notes, and requests to be kept up-to-date with issues, to:\n\
  107. Lewis Williams, 100103.2675@compuserve.com. If you like this program, take a\n\
  108. look at UPCOPY, my bi-directional directory synchronizer. If your gratitude\n\
  109. for it knows no bounds you could register that instead for $25!\n\
  110. ");
  111. }
  112.  
  113. /***********************************************************************
  114. * Subroutine to open files etc.
  115. ***********************************************************************/
  116. int openfils(argc,argv)
  117. int argc;
  118. char *argv[];    /* array of strings */
  119. {
  120. /* Take care of inpfil1 and add defaults if necessary */
  121. switch (argc)
  122.   {
  123.   default:
  124.     fprintf(stderr,"Bad parameters\n");
  125.     return TRUE;
  126.   case 1:
  127.     explain();
  128.     return TRUE;
  129.   case 2:
  130.     strcpy(inpnam1,argv[1]);
  131.     strcpy(inpnam2,"*.bak");    /* default to <filename>.bak if no 2nd file */
  132.     break;
  133.   case 3:
  134.     strcpy(inpnam1,argv[1]);    /* copy both filenames */
  135.     strcpy(inpnam2,argv[2]);
  136.     break;
  137.   case 4:
  138.     strcpy(inpnam1,argv[1]);
  139.     strcpy(inpnam2,argv[2]);
  140.     debug = !(strncmp("/d",argv[3],2));    /* turn on debug facility */
  141.     break;
  142.   }
  143. if ((inpfil1 = fopen(inpnam1,"r")) == NULL)
  144.   {
  145.   fprintf(stderr,"Failed to open input file %s \n",inpnam1);
  146.   return TRUE;
  147.   }
  148. strcpy(ext,"");            /* preset NULL extension */
  149. /* deal with *.something in 2nd name */
  150. if (inpnam2[0]=='*')        /* 2nd base name is wildcard? */
  151.   {
  152.   if (inpnam2[1]=='.')
  153.     strcpy(ext,&inpnam2[1]);    /* 2nd extension */
  154.   strcpy(inpnam2,inpnam1);    /* use input name basically */
  155.   s2 = strchr(inpnam2,'.');    /* pointer to . character=remove 1st extension*/
  156.   strcpy(s2,ext);        /* add 2nd extension nsion to input name */
  157.   }
  158. /* deal with something.* in 2nd name */
  159. s2 = strchr (inpnam2,'.');    /* pointer to new . character */
  160. if (s2[1]=='*')            /* wildcard extension */
  161.   {
  162.   s1 = strchr(inpnam1,'.');    /* . character in 1st name */
  163.   strcpy(s2,s1);
  164.   }
  165. if ((inpfil2 = fopen(inpnam2,"r")) == NULL)
  166.   {
  167.   fprintf(stderr,"Failed to open input file %s \n",inpnam2);
  168.   return TRUE;
  169.   }
  170. return FALSE;            /* all is OK */
  171. }
  172.  
  173. /***********************************************************************
  174. * Typeout the lines after a match is found
  175. ***********************************************************************/
  176. void typeout()
  177. {
  178. if (debug)
  179.   printf("first1=%d,first2=%d,curr1=%d,curr2=%d,beyond1=%d,beyond2=%d,match=%d\n",first1,first2,curr1,curr2,beyond1,beyond2,match);
  180. if ((first1 == first2) && (first1 == 0) && (match != 0))
  181.   /* Files are the same. some lines to type out */
  182.   printf("%s",prog1[0]);
  183. else
  184.   /* files are different */
  185.   /* output lines from file 1 */
  186.   {
  187.   if (match)
  188.     {
  189.     first1--;            /* backup to non-matching lines */
  190.     first2--;
  191.     }
  192.   if (first1>=0)
  193.     printf("### %s\n",inpnam1);    /* header if required */
  194.   for (i=0;i<=first1;i++)
  195.     printf("%s",prog1[i]);
  196.   if (first2 >= 0)
  197.     printf("### %s\n",inpnam2);    /* header as required */
  198.   for (i=0;i<=first2;i++)
  199.     printf("%s",prog2[i]);
  200.   if ((first1 >= 0) || (first2 >= 0))
  201.     printf("### End difference\n");        /* footer as required */
  202.   }
  203. /* Copy data in buffers back to the beginning */
  204. tprintf2("Copying lines %d to %d down in file1\n",first1+1,beyond1-1);
  205. for (i=first1+1;i<=beyond1-1;i++)
  206.   strcpy(prog1[i-first1-1],prog1[i]);
  207. tprintf2("Copying lines %d to %d down in file2\n",first2+1,beyond2-1);
  208. for (i=first2+1;i<=beyond2-1;i++)
  209.   strcpy(prog2[i-first2-1],prog2[i]);
  210. curr1 = -1;                /* set startup situation */
  211. curr2 = -1;
  212. beyond1 = beyond1  - first1 - 1;
  213. beyond2 = beyond2 - first2 - 1;
  214. first1 = 0;
  215. first2 = 0;
  216. if (debug)
  217.   {
  218.   printf("Setting beyond1 = %d and beyond2 = %d\n",beyond1,beyond2);
  219.   printf("Setting curr1 and curr2 to -1\n");
  220.   printf("Setting first1,first2\n");
  221.   }
  222. }
  223.  
  224. /***********************************************************************
  225. * Get next line from file1 or buffer1
  226. ***********************************************************************/
  227. int getlin1()
  228. {
  229. curr1++;            /* point to next line */
  230. tprintf1("Inc'd curr1 to %d\n",curr1);
  231. if (curr1 >= beyond1)        /* 1st buffer is used up */
  232.   {
  233.   tprintf2("First buffer is used up - reading a line curr1 = %d, beyond1 = %d\n",curr1,beyond1);
  234.   if (fgets(prog1[curr1],128,inpfil1)==NULL)    /* end of file 1 */
  235.     {
  236.     curr1 = beyond1 - 1;        /* set line to last available */
  237.     tprintf1("File1 is exhausted. Reset curr1 to beyond1 -1 (%d)\n",curr1);
  238.     return TRUE;            /* failed t